//
//  SlipBackGestureConflictViewController.m
//  TestPrj
//
//  Created by 朱铅峰 on 2020/1/7.
//  Copyright © 2020 Xing. All rights reserved.
//

#import "SlipBackGestureConflictViewController.h"

#pragma mark - iOS Category不要重写原有类方法!!!
#pragma warning iOS Category不要重写原有类方法!!!
/*
 ！！！IOS Category不要重写原有类方法
 
 IOS Category不要重写原有类方法:https://blog.csdn.net/hello_hwc/article/details/43964643
 【iOS】category重写方法的调用:https://blog.csdn.net/JaimeCool/article/details/76071630
 
 第三方库中<BKPhotoBrowser>中UIScrollView+GKGestureHandle.h也重写了方法：
 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
 可能和UIScrollView+CXGestureHandle.h重写该方法产生了冲突，
 导致该案例通过在UIScrollView+CXGestureHandle.h中重写UIView手势的方法来实现的方式无法实现。
 虽然没有在该类中引入<BKPhotoBrowser>，但是由于BKPhotoBrowser通过cocopod引入已被提前编译，
 导致在UIScrollView+GKGestureHandle.h中重写的的方法就无法被调用到。
 在UIScrollView+CXGestureHandle和UIScrollView+GKGestureHandle的gestureRecognizerShouldBegin
 中分别打印日志，就可以看出端倪！
 
 
 本案例的解决方案：通过继承创建一个UIScrollView的子类，在子类中重写该方法，就能够实现了！
 */
//#import "UIScrollView+CXGestureHandle.h"

#import "ConflictGestScrollView.h"

@class UIScrollView;
@interface SlipBackGestureConflictViewController ()

@property(nonatomic,strong) UIView *topView;
@property(nonatomic,strong) ConflictGestScrollView *scrollView;
@property(nonatomic,strong) UISwitch *switchView;

@end

@implementation SlipBackGestureConflictViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.title = @"滑动返回手势冲突解决案例";
    
    [self.view addSubview:self.topView];
    [self.view addSubview:self.scrollView];
    [self configTopView];
    [self configScrollView];
}

/// 初始化头部信息
- (void)configTopView {
    
    UIButton *beforeBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    beforeBtn.frame = CGRectMake(10, 10, 100, 30);
    [beforeBtn setTitle:@"解决前" forState:UIControlStateNormal];
    [beforeBtn setTitleColor:kColorBlack forState:UIControlStateNormal];
    [beforeBtn addTarget:self action:@selector(beforeAction) forControlEvents:UIControlEventTouchUpInside];
    [self.topView addSubview:beforeBtn];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 50, 30)];
    label.textColor = [UIColor blackColor];
    label.text = @"适配:";
    [self.topView addSubview:label];
    
    self.switchView.frame = CGRectMake(60, 50, 50, 30);
    [self.topView addSubview:self.switchView];
}

/// 初始化ScollView子视图
- (void)configScrollView {
    
    UIView *firstView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
    firstView.backgroundColor = [UIColor greenColor];
    [self.scrollView addSubview:firstView];
    
    UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(5, 50, firstView.width-10, 30)];
    slider.minimumValue = 0;
    slider.maximumValue = 10;
    slider.value = 5;
    [firstView addSubview:slider];
    
    UIView *secondView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
    secondView.left = firstView.right;
    secondView.backgroundColor = [UIColor redColor];
    [self.scrollView addSubview:secondView];
    
    UISlider *slider1 = [[UISlider alloc] initWithFrame:CGRectMake(0, 50, secondView.width-20, 30)];
    slider1.minimumValue = 0;
    slider1.maximumValue = 10;
    slider1.value = 5;
    [secondView addSubview:slider1];
    
    UIView *thirdView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
    thirdView.left = secondView.right;
    thirdView.backgroundColor = [UIColor yellowColor];
    [self.scrollView addSubview:thirdView];
    
    self.scrollView.contentSize = CGSizeMake(thirdView.right, self.scrollView.height);
}

/// 解决前
- (void)beforeAction {
    
    NSMutableString *content = [NSMutableString string];
    [content appendString:@"1、UIScrollView的左右滑动导致vc的滑动返回失效\n"];
    [content appendString:@"2、UIScrollView的左右滑动导致快速点击并拖拽UISlider失效，需要按住UISlider一小段时间后才能生效\n"];
    [content appendString:@"3、UISlider太靠左边与滑动返回产生冲突(触发了滑动返回而不是UISlider的事件)"];
    
    [Utils showAlertViewWithTitle:@"冲突描述"
                          content:content
                      buttonTitle:@"好的"
                         targetVC:self];
}

/// 适配开关值变化事件
- (void)switchViewChangeValueAction:(UISwitch *)sender {
    
    //======================== 1
    //解决UIScrollView横向滑动和滑动返回手势冲突的方案，详见Category类
    self.scrollView.cx2_gestureHandleEnabled = sender.on;
    
    
    //======================== 2
    /*
     解决UISlider需要按住一会儿才能触发UISlider自身事件的方案一：
     
     delaysContentTouches默认值为YES表示延迟scrollView上子视图的响应，
     所以当直接拖动UISlider时，如果此时touch时间在150ms以内，UIScrollView会认为是拖动自己，
     从而拦截了event，导致UISlider接收不到滑动的event。但是只要长按住UISlider一会儿再拖动，
     此时touch时间超过150ms，因此滑动的event会发送到UISlider上，
     然后UISlider再作出响应；设置为NO后，拖动UISlider时就可以直接做出响应，
     解决了UISlider与UIScrollView之间的冲突，同时也解决了向右拖拽时却触发了全屏侧滑pop返回的问题。
     */
    self.scrollView.delaysContentTouches = !sender.on;
    /*
     解决UISlider需要按住一会儿才能触发UISlider自身事件的方案二：
     
     //拦截事件的处理 事件传递给谁，就会调用谁的hitTest:withEvent:方法。
     //处理UISlider的滑动与UIScrollView的滑动事件冲突
     - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    //直接拖动UISlider，此时touch时间在150ms以内，UIScrollView会认为是拖动自己，从而拦截了event，导致UISlider接受不到滑动的event。但是只要按住UISlider一会再拖动，此时此时touch时间超过150ms，因此滑动的event会发送到UISlider上。
         UIView *view = [super hitTest:point withEvent:event];
         
         if([view isKindOfClass:[UISlider class]]) {
             //如果接收事件view是UISlider,则scrollview禁止响应滑动
             self.scrollEnabled = NO;
         } else {   //如果不是,则恢复滑动
             self.scrollEnabled = YES;
         }
         return view;
     }
     */
}


//======================== 3
// 2解决完之后，UISlider太靠左边与滑动返回产生冲突的解决方案
// 在支持全屏侧滑返回的UINavigationController的子类WSLNavigatioController中，遵守协议<UIGestureRecognizerDelegate>,实现如下方法：
////触发之后是否响应手势事件
////处理侧滑返回与UISlider的拖动手势冲突
//- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
//
//    NSLog(@"%s",__func__);
//
//    //如果手势是触摸的UISlider滑块触发的，侧滑返回手势就不响应
//    if ([touch.view isKindOfClass:[UISlider class]]) {
//        return NO;
//    }
//    return YES;
//}

#pragma mark - 懒加载

- (UIView *)topView {
    
    if (!_topView) {
        _topView = [[UIView alloc] initWithFrame:CGRectMake(0, kNavBarHeight, self.view.width, 100)];
        _topView.backgroundColor = [UIColor whiteColor];
    }
    
    return _topView;
}

- (UIScrollView *)scrollView {
    
    if (!_scrollView) {
        _scrollView = [[ConflictGestScrollView alloc] initWithFrame:CGRectMake(0, self.topView.bottom, self.view.width, self.view.height-self.topView.bottom)];
        _scrollView.pagingEnabled = YES;
    }
    return _scrollView;
}

- (UISwitch *)switchView {
    
    if (!_switchView) {
        _switchView = [[UISwitch alloc] init];
        //_switchView.tintColor = [UIColor redColor];
        //_switchView.onTintColor = [UIColor blackColor];
        //_switchView.thumbTintColor = [UIColor whiteColor];
        [_switchView addTarget:self action:@selector(switchViewChangeValueAction:) forControlEvents:UIControlEventValueChanged];
    }
    
    return _switchView;
}

@end
